package com.tiger.admin.http.apps;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.tiger.admin.Db;
import com.tiger.admin.SaveOperateLog;
import com.tiger.admin.http.apps.category.AppCategoryService;
import com.tiger.admin.http.apps.dto.AppPage;
import com.tiger.admin.http.apps.type.AppRes;
import com.tiger.admin.dto.PaginationResult;
import com.tiger.common.UploadService;
import com.tiger.db.entity.App;
import com.tiger.db.entity.AppCategory;
import com.tiger.utils.ResponseUtil;
import com.tiger.utils.Utils;
import org.springframework.beans.BeanUtils;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.time.Instant;
import java.util.*;

@RestController
@RequestMapping("/app")
public class AppController {
    private final UploadService uploadService;

    private final AppCategoryService appCategoryService;
    private final AppService appService;
    private final Db db;

    public AppController(UploadService uploadService, AppCategoryService appCategoryService, AppService appService, Db db) {
        this.uploadService = uploadService;
        this.appCategoryService = appCategoryService;
        this.appService = appService;
        this.db = db;
    }

    /**
     * 导入某个分类的app
     * **/
    @SaveOperateLog("导入服务")
    @PostMapping("import/{category}")
    public Object importApps(@RequestParam("file") MultipartFile file, @PathVariable("category") Integer category, @RequestAttribute("memberId") long memberId) {

        appService.importApps(file, category, false);

        return ResponseUtil.successRes();
    }

    /**
     * 导入待办app
     * **/
    @SaveOperateLog("导入待办")
    @PostMapping("importtaskapp")
    public Object importApps(@RequestParam("file") MultipartFile file, @RequestAttribute("memberId") long memberId) {

        appService.importApps(file, 0, true);

        return ResponseUtil.successRes();
    }

    @PostMapping("upload")
    public Object uploadPic(@RequestParam("pic") MultipartFile file, @RequestAttribute("memberId") long memberId) {
        String fileName = uploadService.put(file, String.valueOf(memberId));
        return ResponseUtil.successRes(fileName);
    }

    /**
     * 应用分页
     * **/
    @PostMapping("page")
    public Object page(@RequestBody AppPage page, @RequestAttribute("memberId") long memberId) {
        PaginationResult<AppRes> result = new PaginationResult<>();

        LambdaQueryWrapper<App> wrapper = new LambdaQueryWrapper<>();

        wrapper.orderByDesc(App::getSort, App::getId);


        if(page.getRecommend() != null) {
            wrapper.eq(App::getRecommend, page.getRecommend());
        }

        wrapper.eq(App::getTaskApp, page.getTaskApp());

        if(page.getName() != null && !page.getName().isEmpty()) {
            wrapper.like(App::getName, page.getName());
        }

        if(page.getSourceKey() != null && !page.getSourceKey().isEmpty()) {
            wrapper.eq(App::getSourceKey, page.getSourceKey());
        }



        if(page.getCategory() != null && page.getCategory() > 0) {
            AppCategory category = db.appCategory.getOne(new LambdaQueryWrapper<AppCategory>().select(AppCategory::getParentId, AppCategory::getTopId).eq(AppCategory::getId, page.getCategory()));
            if(category == null) return ResponseUtil.successRes(result);

            List<AppCategory> categories = db.appCategory.list(new LambdaQueryWrapper<AppCategory>().select(AppCategory::getId, AppCategory::getParentId).eq(AppCategory::getTopId, category.getTopId() == 0 ? page.getCategory() : category.getTopId()));
            List<Integer> subIds = new ArrayList<>();
            appCategoryService.querySubCategory(categories, subIds, page.getCategory());

            if(subIds.isEmpty()) {
                wrapper.eq(App::getCategory, page.getCategory());
            }else {
                subIds.add(page.getCategory());
                wrapper.in(App::getCategory, subIds);
            }
        }


        long total = db.app.count(wrapper);
        if(total > 0) {
            result.setTotal(total);

            wrapper.orderByDesc(App::getSort);
            wrapper.orderByDesc(App::getId);

            List<App> rows = db.app.pagination(wrapper, page.getPageNo(), page.getPageSize());

            List<Integer> ids = new ArrayList<>();

            for(App row : rows) {
                if(!ids.contains(row.getCategory())) {
                    ids.add(row.getCategory());
                }
            }

            LambdaQueryWrapper<AppCategory> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.select(AppCategory::getId, AppCategory::getName);
            if(ids.size() == 1) {
                queryWrapper.eq(AppCategory::getId, ids.get(0));
            }else {
                queryWrapper.in(AppCategory::getId, ids);
            }

            List<AppCategory> categories = db.appCategory.list();
            Map<Integer, AppCategory> cateMap = new HashMap<>();

            for (AppCategory cate : categories) {
                cateMap.put(cate.getId(), cate);
            }

            List<AppRes> apps = new ArrayList<>();

            for(App row : rows) {
                AppRes appRes = new AppRes();
                BeanUtils.copyProperties(row, appRes);

                appRes.setCategoryNames(new ArrayList<>());

                AppCategory category = cateMap.get(row.getCategory());
                if(category != null) {
                    if(category.getParentId() > 0) {
                        AppCategory parent = cateMap.get(category.getParentId());
                        if(parent != null) {
                            appRes.getCategoryNames().add(parent.getName());
                        }
                    }

                    appRes.getCategoryNames().add(category.getName());
                }

                apps.add(appRes);
            }

            result.setRows(apps);
        }


        return ResponseUtil.successRes(result);
    }

    @SaveOperateLog("新增服务")
    @PostMapping("add")
    public Object add(@RequestBody @Validated App data, @RequestAttribute("memberId") long memberId) {
        if(db.app.exists(new LambdaQueryWrapper<App>().eq(App::getCategory, data.getCategory()).eq(App::getName, data.getName()))) {
            return ResponseUtil.failRes("已存在相同的名称");
        }

        //App row = new App();


        //BeanUtils.copyProperties(data, row);

        Instant now = Instant.now();

        data.setCreateTime(now.getEpochSecond());
        data.setCreatorId(memberId);


        boolean r = db.app.save(data);

        return r ? ResponseUtil.successRes(data) : ResponseUtil.failRes();

    }

    @SaveOperateLog("修改服务")
    @PostMapping("update/{id}")
    public Object add(@RequestBody @Validated App data, @PathVariable Long id, @RequestAttribute("memberId") long memberId) {
        App row = db.app.getById(id);
        if(row == null) return ResponseUtil.successRes();
        if(data.getName() != null && !Objects.equals(data.getName(), row.getName())) {
            if(db.app.exists(new QueryWrapper<App>().eq("name", data.getName()))) {
                return ResponseUtil.failRes("已存在相同的名称");
            }
        }


        Instant now = Instant.now();

        Utils.copyPropertiesIgnoreNull(data, row);

        row.setId(id);
        row.setUpdateTime(now.getEpochSecond());


        boolean r = db.app.updateById(row);

        return r ? ResponseUtil.successRes(row) : ResponseUtil.failRes();

    }

    @SaveOperateLog("删除服务")
    @PostMapping("delete/{id}")
    public Object del(@PathVariable long id, @RequestAttribute("memberId") long memberId) {
        App row = db.app.getOne(new QueryWrapper<App>().select("id").eq("id", id));
        if(row == null) return ResponseUtil.successRes();
        boolean r = db.app.removeById(id);
        return r ? ResponseUtil.successRes() : ResponseUtil.failRes();
    }

}
